﻿using A2DFramework.SQLDispatcherService.Configuration;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;

namespace A2DFramework.SQLDispatcherService
{
    public class ConnectionManager
    {
        /// <summary>
        /// 获取可写入的数据库连接字符串
        /// </summary>
        /// <returns></returns>
        private static string GetWritableDbConnectionString(string connectionName)
        {
            return Configuration.SQLDispatcherConfiguration.Connections[connectionName].WritableDB.ConnectionString;
        }

        /// <summary>
        /// 获取默认的可读数据库连接字符串
        /// </summary>
        /// <returns></returns>
        private static string GetReadableDbConnectionString(string connectionName)
        {
            return GetReadableDbConnectionString(connectionName, string.Empty);
        }

        /// <summary>
        /// 获取特定Region的可读数据库连接字符串
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        private static string GetReadableDbConnectionString(string connectionName, string region)
        {
            if (region == null || region.Length == 0)       //from normal read dbs
            {
                int random = GenerateRandomNumber();
                int dbIndex = random % Configuration.SQLDispatcherConfiguration.Connections[connectionName].ReadDBs.Count;
                return Configuration.SQLDispatcherConfiguration.Connections[connectionName].ReadDBs[dbIndex].ConnectionString;
            }

            DedicatedRegion r = Configuration.SQLDispatcherConfiguration.Connections[connectionName].DedicatedRegions.Find(t => t.Region.Equals(region, StringComparison.OrdinalIgnoreCase));
            if (r == null)
                throw new Exception("No such Dedicated Region Identifier.");

            {
                int random = GenerateRandomNumber();
                int dbIndex = random % r.DBs.Count;
                return r.DBs[dbIndex].ConnectionString;
            }
        }

        public static string GetDbConnectionString(ConnectionOption option)
        {
            bool targetDb_Should_Be_Writable = false;

            if (option.ExecuteType == SqlExecuteType.Write)
                targetDb_Should_Be_Writable = true;

            if (targetDb_Should_Be_Writable)
                return GetWritableDbConnectionString(option.ConnectionName);

            return GetReadableDbConnectionString(option.ConnectionName, option.DedicatedRegion);
        }

        public static SqlConnection GetSqlConnection(ConnectionOption option)
        {
            return new SqlConnection(GetDbConnectionString(option));
        }

        private static bool ExistsSQLKeyword(string keyword, string sql)
        {
            List<string> keywords = new List<string>();
            keywords.Add(string.Format("{0} ", keyword));
            keywords.Add(string.Format("{0}\r", keyword));
            keywords.Add(string.Format("{0}\n", keyword));
            keywords.Add(string.Format("{0}\r\n", keyword));
            keywords.Add(string.Format("{0}\t", keyword));

            foreach(var kw in keywords)
                if (sql.IndexOf(kw, StringComparison.OrdinalIgnoreCase) >= 0)
                    return true;

            return false;
        }

        private static int GenerateRandomNumber()
        {
            long tick = DateTime.Now.Ticks;

            Random Random1 = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));

            //产生0到1000的随机数
            int i1 = Random1.Next(0, 1001);

            return i1;
        }
    }
}
